package com.lishe.lishe.lishe.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.lishe.lishe.R;


/**
 * 条形进度条
 * Created by lwa on 2017/8/31.
 */

public class LineProgressBar extends View {

    Context context;

    public LineProgressBar(Context context) {
        super(context);
        this.context = context;
        createPaint();
    }

    public LineProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init(attrs);
        createPaint();
    }

    public LineProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init(attrs);
        createPaint();
    }

    //view的宽高
    int width = 0;
    int height = 0;

    private Paint paintBar;//进度条画笔
    private Paint paintSid;//进度条边框画笔
    private Paint paintTex;//文字条画笔

    private float left = 0;
    private float right = 0;
    private float top = 0;
    private float bottom = 0;

    private float corner = 20;//圆角
    private int sidColor = Color.RED;//外框颜色
    private float sidSize = 8;//外框线条大小
    private int barColor = Color.GRAY;//进度条颜色
    private float barSize = 80;//进度大小
    private float maxProgress = 100;//进度条总值
    private float cutProgress = 0;//当前进度值
    private int barAlph = 0;//进度条透明
    private int sidAlph = 0;//边框透明进度值

    /**
     * 初始化
     */
    private void init(AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LineProgressBar);
        corner = array.getFloat(R.styleable.LineProgressBar_corner, 0);
        sidColor = array.getColor(R.styleable.LineProgressBar_sidColor, Color.RED);
        barColor = array.getColor(R.styleable.LineProgressBar_barColor, Color.GRAY);
        sidSize = array.getFloat(R.styleable.LineProgressBar_sidSize, 0);
        barSize = array.getFloat(R.styleable.LineProgressBar_barSize, 0);
        maxProgress = array.getFloat(R.styleable.LineProgressBar_maxProgress, 100);
        cutProgress = array.getFloat(R.styleable.LineProgressBar_progress, 0);
        barAlph = array.getInt(R.styleable.LineProgressBar_barAlph, 255);
        sidAlph = array.getInt(R.styleable.LineProgressBar_sidAlph, 255);
        array.recycle();
    }

    /**
     * 创建画笔
     */
    private void createPaint() {
        //进度条画笔
        paintBar = new Paint();
        paintBar.setAntiAlias(true);//抗锯齿
        paintBar.setDither(true);//防抖动
        paintBar.setStyle(Paint.Style.FILL);//填充
        paintBar.setColor(barColor);//颜色
        paintBar.setStrokeWidth(sidSize);
        paintBar.setAlpha(barAlph);
        //进度条边框画笔
        paintSid = new Paint();
        paintSid.setAntiAlias(true);//抗锯齿
        paintSid.setDither(true);//防抖动
        paintSid.setStyle(Paint.Style.STROKE);//空心
        paintSid.setColor(sidColor);//颜色
        paintSid.setStrokeWidth(sidSize);
        paintSid.setAlpha(sidAlph);
    }

    /**
     * 绘制边框
     *
     * @param canvas
     */
    private void drawSid(Canvas canvas) {
        //非marting --边框0.0--1080.0--0.0--120.0
        //marting --边框15.0--1065.0--15.0--135.0  --marting5dp
        Log.e("开始绘画", "--边框" + width + "--" + height);
        Log.e("开始绘画", "--边框" + left + "--" + right + "--" + top + "--" + bottom);
        //因为笔芯位置为（0，0）所以要加上边框宽度的一半,b保证转角遇边的平滑
        RectF rectF = new RectF(0 + sidSize / 2, 0 + sidSize / 2, width - sidSize / 2, height - sidSize / 2);
        canvas.drawRoundRect(rectF, corner, corner, paintSid);//圆角矩形
    }

    /**
     * 绘制进度
     *
     * @param canvas
     */
    private void drawBar(Canvas canvas) {
        Log.e("开始绘画", "--进度条");
        float progress = cutProgress / maxProgress;
        float r = (width) * progress;
        float left = sidSize / 2;//取一半
        float top = sidSize / 2;
        float right = width - sidSize / 2;
        float bottom = height - sidSize / 2;
        if (corner>(height-2*sidSize)/2){
            corner=(height-2*sidSize)/2;
        }
        Path path = new Path();
        path.moveTo(left, top + corner);
        if (progress <= corner / width) {//画前半弧//根据进度比例和弧度占总宽的比例判断是否在画前半弧
            double angle = Math.acos((corner - r) / corner);//圆弧角度变化
            path.arcTo(new RectF(left, top, left + 2 * corner, top + 2 * corner), 180, (float) (angle * 180 / Math.PI));//上圆弧
            path.arcTo(new RectF(left, bottom - 2 * corner, left + 2 * corner, bottom), 180 - (float) (angle * 180 / Math.PI), (float) (angle * 180 / Math.PI));//下圆弧
            path.close();
            canvas.drawPath(path, paintBar);
        } else if (progress <= (width - corner) / width) {//画中间直线//根据进度比例和除去弧度后的宽度占总宽的比例判断是否在画后半弧
            path.arcTo(new RectF(left, top, left + 2 * corner, top + 2 * corner), 180, 90);
            path.lineTo(left + (cutProgress / maxProgress) * (right - left), top);
            path.lineTo(left + (cutProgress / maxProgress) * (right - left), bottom);
            path.lineTo(left + corner, bottom);
            path.arcTo(new RectF(left, bottom - 2 * corner, left + 2 * corner, bottom), 90, 90);
            path.close();
            canvas.drawPath(path, paintBar);

        } else {//画后半弧
            float a = r - (width - corner);
            double angle = Math.asin(a / corner);
            path.arcTo(new RectF(left, top, left + 2 * corner, top + 2 * corner), 180, 90);
            path.arcTo(new RectF(right - 2 * corner, top, right, top + 2 * corner), 270, (float) (angle * 180 / Math.PI));
            path.arcTo(new RectF(right - 2 * corner, bottom - 2 * corner, right, bottom), (float) (90 - (angle * 180 / Math.PI)), (float) (angle * 180 / Math.PI));
            path.arcTo(new RectF(left, bottom - 2 * corner, left + 2 * corner, bottom), 90, 90);
            path.close();
            canvas.drawPath(path, paintBar);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        this.left = left;
        this.right = right;
        this.top = top;
        this.bottom = bottom;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    /**
     * 测量
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec 1.精确模式（MeasureSpec.EXACTLY）
     *                          <p>
     *                          在这种模式下，尺寸的值是多少，那么这个组件的长或宽就是多少。
     *                          <p>
     *                          2.最大模式（MeasureSpec.AT_MOST）
     *                          <p>
     *                          这个也就是父组件，能够给出的最大的空间，当前组件的长或宽最大只能为这么大，当然也可以比这个小。
     *                          <p>
     *                          3.未指定模式（MeasureSpec.UNSPECIFIED）
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heigthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heigthMode = MeasureSpec.getMode(widthMeasureSpec);

        final int minimumWidth = getSuggestedMinimumWidth();
        final int minimumHeight = getSuggestedMinimumHeight();
        Log.e("YView", "---minimumWidth = " + minimumWidth + "");
        Log.e("YView", "---minimumHeight = " + minimumHeight + "");
        width = measureWidth(minimumWidth, widthMeasureSpec);
        height = measureHeight(minimumHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);

    }

    private int measureWidth(int defaultWidth, int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        Log.e("YViewWidth", "---speSize = " + specSize + "");

        switch (specMode) {
            case MeasureSpec.AT_MOST:
//                defaultWidth = (int) mPaint.measureText(mText) + getPaddingLeft() + getPaddingRight();
                defaultWidth = getPaddingLeft() + getPaddingRight();
                Log.e("YViewWidth", "---speMode = AT_MOST");
                break;
            case MeasureSpec.EXACTLY:
                Log.e("YViewWidth", "---speMode = EXACTLY");
                defaultWidth = specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                Log.e("YViewWidth", "---speMode = UNSPECIFIED");
                defaultWidth = Math.max(defaultWidth, specSize);
        }
        return defaultWidth;
    }

    private int measureHeight(int defaultHeight, int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        Log.e("YViewHeight", "---speSize = " + specSize + "");
        switch (specMode) {
            case MeasureSpec.AT_MOST:
//                defaultHeight = (int) (-mPaint.ascent() + mPaint.descent()) + getPaddingTop() + getPaddingBottom();
                defaultHeight = getPaddingTop() + getPaddingBottom();
                Log.e("YViewHeight", "---speMode = AT_MOST");
                break;
            case MeasureSpec.EXACTLY:
                defaultHeight = specSize;
                Log.e("YViewHeight", "---speSize = EXACTLY");
                break;
            case MeasureSpec.UNSPECIFIED:
                defaultHeight = Math.max(defaultHeight, specSize);
                Log.e("YViewHeight", "---speSize = UNSPECIFIED");
//        1.基准点是baseline
//        2.ascent：是baseline之上至字符最高处的距离
//        3.descent：是baseline之下至字符最低处的距离
//        4.leading：是上一行字符的descent到下一行的ascent之间的距离,也就是相邻行间的空白距离
//        5.top：是指的是最高字符到baseline的值,即ascent的最大值
//        6.bottom：是指最低字符到baseline的值,即descent的最大值
                break;
        }
        return defaultHeight;

    }

    /**
     * 绘制
     *
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawSid(canvas);
        drawBar(canvas);

    }

    /**
     * 设置进度值
     *
     * @param progress
     */
    public void setProgress(int progress) {
        cutProgress = progress > maxProgress ? maxProgress : progress;
        refresh();
    }

    /**
     * 条形框的角度（圆角设置）
     *
     * @param corner
     */
    public void setCorner(float corner) {
        this.corner = corner;
    }

    /**
     * 外框颜色
     *
     * @param color
     */
    public void setSidColor(int color) {
        sidColor = color;
    }

    /**
     * 进度条颜色
     *
     * @param color
     */
    public void setBarColor(int color) {
        barColor = color;
    }

    /**
     * 进度条动画
     */
    public void setAnimationAAA() {
        ObjectAnimator animator = ObjectAnimator.ofInt(this, "progress", 100).setDuration(10000);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
        animator.start();
    }

    private void refresh() {
        if (Looper.getMainLooper() == Looper.myLooper()) {
            invalidate();
        } else {
            postInvalidate();
        }
    }


}
